﻿/**********************************************************\
*  TinyLib - InputManager                                  *
*                                                          *
*  Handles input from keyboard, mouse and XBOX controllers.*
*                                                          *
* (c) Jens Berglind                                        *
*                                                          *
* Last edited by Jens Berglind 25-06-2012                  *
\**********************************************************/ 

using System;
using System.Collections.Generic;

using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Input;

namespace AALib.Input
{
    public class InputManager : GameComponent
    {
        #region Fields

        private KeyboardState m_currentKeyState, m_lastKeyState;
        private MouseState m_currentMouseState, m_lastMouseState;
        private GamePadState m_currentPadState, m_lastPadState; //gör dessa till en lista i en container istället
        private GamePadState m_currentPadState2, m_lastPadState2;
        private GamePadState m_currentPadState3, m_lastPadState3;
        private GamePadState m_currentPadState4, m_lastPadState4;

        public Vector2 m_mouseAbsolutePosition = Vector2.Zero;
        public Vector2 m_mouseRelativePosition = Vector2.Zero;

        public enum MouseButtons
        {
            LEFT,
            RIGHT,
            XBUTTON1,
            XBUTTON2
        }

        #endregion

        #region Inits

        public InputManager(Game p_game)
            : base(p_game)
        {
        }

        #endregion

        #region Keyboard Commands

        public bool bJustPressed(Keys p_key)
        {
            return m_currentKeyState.IsKeyDown(p_key) && m_lastKeyState.IsKeyUp(p_key);
        }

        public bool bJustreleased(Keys p_key)
        {
            return m_currentKeyState.IsKeyUp(p_key) && m_lastKeyState.IsKeyDown(p_key);
        }

        public bool bIsDown(Keys p_key)
        {
            return m_currentKeyState.IsKeyDown(p_key);
        }

        #endregion

        #region Mouse Commands

        public bool bJustPressed(MouseButtons p_button)
        {
            return bIsDown(m_currentMouseState, p_button) && !bIsDown(m_lastMouseState, p_button);
        }

        public bool bJustReleased(MouseButtons p_button)
        {
            return !bIsDown(m_currentMouseState, p_button) && bIsDown(m_lastMouseState, p_button);
        }

        // Is button down without mousestate
        public bool bIsDown(MouseButtons p_button)
        {
            switch (p_button)
            {
                case MouseButtons.LEFT:
                    return m_currentMouseState.RightButton == ButtonState.Pressed ? true : false;
                case MouseButtons.RIGHT:
                    return m_currentMouseState.LeftButton == ButtonState.Pressed ? true : false;
                case MouseButtons.XBUTTON1:
                    return m_currentMouseState.XButton1 == ButtonState.Pressed ? true : false;
                case MouseButtons.XBUTTON2:
                    return m_currentMouseState.XButton2 == ButtonState.Pressed ? true : false;
                default:
                    return false;
            }
        }

        // Is button down with MouseState
        public bool bIsDown(MouseState p_mouseState, MouseButtons p_button)
        {
            switch (p_button)
            {
                case MouseButtons.LEFT:
                    return m_currentMouseState.RightButton == ButtonState.Pressed ? true : false;
                case MouseButtons.RIGHT:
                    return m_currentMouseState.LeftButton == ButtonState.Pressed ? true : false;
                case MouseButtons.XBUTTON1:
                    return m_currentMouseState.XButton1 == ButtonState.Pressed ? true : false;
                case MouseButtons.XBUTTON2:
                    return m_currentMouseState.XButton2 == ButtonState.Pressed ? true : false;
                default:
                    return false;
            }
        }

        #endregion

        #region GamePad Commands

        //GamePadState padState1 = GamePad.GetState(PlayerIndex.One);

        public bool m_bJustPressed(Buttons p_button, int p_playerNr)
        {
            switch (p_playerNr)
            {
                case 1:
                    return m_currentPadState.IsButtonDown(p_button) && m_lastPadState.IsButtonUp(p_button);
                case 2:
                    return m_currentPadState2.IsButtonDown(p_button) && m_lastPadState2.IsButtonUp(p_button);
                case 3:
                    return m_currentPadState3.IsButtonDown(p_button) && m_lastPadState3.IsButtonUp(p_button);
                case 4:
                    return m_currentPadState4.IsButtonDown(p_button) && m_lastPadState4.IsButtonUp(p_button);
                default:
                    return m_currentPadState.IsButtonDown(p_button) && m_lastPadState.IsButtonUp(p_button);
            }
        }

        public bool bJustReleased(Buttons p_button, int p_playerNr)
        {
            switch (p_playerNr)
            {
                case 1:
                    return m_currentPadState.IsButtonUp(p_button) && m_lastPadState.IsButtonDown(p_button);
                case 2:
                    return m_currentPadState2.IsButtonUp(p_button) && m_lastPadState2.IsButtonDown(p_button);
                case 3:
                    return m_currentPadState3.IsButtonUp(p_button) && m_lastPadState3.IsButtonDown(p_button);
                case 4:
                    return m_currentPadState4.IsButtonUp(p_button) && m_lastPadState4.IsButtonDown(p_button);
                default:
                    return m_currentPadState.IsButtonUp(p_button) && m_lastPadState.IsButtonDown(p_button);
            }
        }

        public bool bIsDown(Buttons p_button, int p_playerNr)
        {
            switch (p_playerNr)
            {
                case 1:
                    return m_currentPadState.IsButtonDown(p_button);
                case 2:
                    return m_currentPadState2.IsButtonDown(p_button);
                case 3:
                    return m_currentPadState3.IsButtonDown(p_button);
                case 4:
                    return m_currentPadState4.IsButtonDown(p_button);
                //  default:
                //    return currentPadState.IsButtonDown(button);
            }
            return false;
        }

        #endregion

        #region Update

        public override void Update(GameTime p_gameTime)
        {
            #region Keyboard Update

            m_lastKeyState = m_currentKeyState;
            m_currentKeyState = Keyboard.GetState();

            #endregion

            #region Mouse Update

            m_lastMouseState = m_currentMouseState;
            m_currentMouseState = Mouse.GetState();

            m_mouseRelativePosition = new Vector2(m_currentMouseState.X - m_lastMouseState.X, m_currentMouseState.Y - m_lastMouseState.Y);
            // Mouse positions
            m_mouseAbsolutePosition = new Vector2(m_currentMouseState.X, m_currentMouseState.Y);
           // mouseRelativePosition = new Vector2(lastMouseState.X - currentMouseState.X, lastMouseState.Y - currentMouseState.Y);
            

            #endregion

            #region GamePad Update

            m_lastPadState = m_currentPadState;
            m_currentPadState = GamePad.GetState(PlayerIndex.One);

            m_lastPadState2 = m_currentPadState2;
            m_currentPadState2 = GamePad.GetState(PlayerIndex.Two);

            m_lastPadState3 = m_currentPadState3;
            m_currentPadState3 = GamePad.GetState(PlayerIndex.Three);

            m_lastPadState4 = m_currentPadState4;
            m_currentPadState4 = GamePad.GetState(PlayerIndex.Four);

            #endregion

            base.Update(p_gameTime);
        }

        #endregion
    }
}
